package session

import (
	"github.com/antchfx/xmlquery"
	"os"
	"sync"
	"fmt"
)

type DbProperty struct {
	Driver 			string
	Url             string
	UserName        string
	Password        string
	DataBase        string
}

type DbType string

const (
	MySqlDb 		DbType="mysql"
	OracleDb		DbType="oracle"
	SqlServerDb		DbType="sqlserver"
)

//数据源功能类型
//读写
//只读
//只写
type DbFunc  string

const (
	RW_Func  DbFunc="rw"
	R_Func	 DbFunc="r"
	W_Func	 DbFunc="w"
)

type SqlSessionFactory struct {
	Env             string			//开发  测试  预发布  线上
	//DataSourceType  string
	DbM             map[string]map[string]DbProperty  	//多数据源 单个数据源读写分离问题
	once            sync.Once
}

/*
	构建数据库连接会话
	获取数据连接
 */
func NewSqlSessionFactory(path string)*SqlSessionFactory{
	fc:= &SqlSessionFactory{
		Env:      "",
		DbM:      make(map[string]map[string]DbProperty,0),
	}
	//配置文件中读取配置
	c, err := os.OpenFile(path, os.O_RDWR, 0777)
	if err!=nil{
		panic(fmt.Sprintf("read sql session factory config failed:%v",err))
	}

	doc, err := xmlquery.Parse(c)
	if err!=nil{
		panic(fmt.Sprintf("xml query parse error:%v",err))
	}

	root, err := xmlquery.Query(doc, "//configuration/environments")
	if err!=nil{
		panic(fmt.Sprintf("read xml config error：%v",err))
	}

	//获取当前环境 生产，测试，预发布，线上
	for _,attr:=range root.Attr{
		if attr.Name.Local=="default"{
			fc.Env=attr.Value
		}
	}

	//外层map针对数据源，内层针对不同数据源的不同读写类型
	dbm:=make(map[string]map[string]DbProperty)

	for _,e:=range root.SelectElements("environment"){
		if e!=nil && len(e.Attr)>0{
			if e.Attr[0].Name.Local=="env"{
				if e.Attr[0].Value==fc.Env{
					//获取事务管理 todo
					e.SelectElement("transactionManager")

					//获取连接属性
					for _,dataSourceAttr:=range e.SelectElements("dataSource") {

						if dataSourceAttr != nil && len(dataSourceAttr.Attr) > 0 {
							if dataSourceAttr.Attr[0].Name.Local == "type" {
								_, ok := dbm[dataSourceAttr.Attr[0].Value]
								if !ok {
									dbm[dataSourceAttr.Attr[0].Value] = make(map[string]DbProperty)
								}
							}

							if dataSourceAttr.Attr[1].Name.Local == "func" {
								if _,ok := dbm[dataSourceAttr.Attr[0].Value][dataSourceAttr.Attr[1].Value];ok{
									//存在当前数据源下 当前功能类型的配置
									continue
								}
							}
						}

						dbProperty:=DbProperty{}
						for _, property := range dataSourceAttr.SelectElements("property") {
							if property.Attr != nil && len(property.Attr) > 1 {
								if property.Attr[0].Name.Local != "name" {
									continue
								}

								switch property.Attr[0].Value {
								case "driver":
									if property.Attr[1].Name.Local == "value" {
										dbProperty.Driver = property.Attr[1].Value
									}
								case "url":
									if property.Attr[1].Name.Local == "value" {
										dbProperty.Url = property.Attr[1].Value
									}
								case "username":
									if property.Attr[1].Name.Local == "value" {
										dbProperty.UserName = property.Attr[1].Value
									}
								case "password":
									if property.Attr[1].Name.Local == "value" {
										dbProperty.Password = property.Attr[1].Value
									}
								case "database":
									if property.Attr[1].Name.Local == "value" {
										dbProperty.DataBase = property.Attr[1].Value
									}
								}
							}
						}
						dbm[dataSourceAttr.Attr[0].Value][dataSourceAttr.Attr[1].Value]=dbProperty
					}
				}
			}
		}
	}
	fc.DbM=dbm
	return fc
}